from typing import List, Dict, Any, Optional
from datetime import datetime, time, date
from dataclasses import dataclass

from ..models.audit_models import AuditRequest, RuleResult, RulePriority
from ..utils.logger import get_logger

logger = get_logger(__name__)


@dataclass
class SimpleRuleResult:
    """简化的规则检查结果."""
    passed: bool
    score: float
    message: str
    details: Optional[Dict[str, Any]] = None


class SimpleRuleEngine:
    """简化的规则引擎，只基于用户提供的数据进行评判."""
    
    def __init__(self):
        self.rules = [
            self.check_time_conflict,
            self.check_applicant_info,
            self.check_time_reasonableness,
            self.check_purpose_classification,
            self.check_capacity_utilization,
            self.check_equipment_availability
        ]
    
    def execute_rules(self, request: AuditRequest) -> List[RuleResult]:
        """执行所有规则检查."""
        results = []
        
        for rule_func in self.rules:
            try:
                start_time = datetime.now()
                result = rule_func(request)
                execution_time = (datetime.now() - start_time).total_seconds() * 1000
                
                rule_result = RuleResult(
                    rule_name=rule_func.__name__.replace('check_', '').replace('_', ' ').title(),
                    rule_id=rule_func.__name__,
                    matched=result.passed,
                    message=result.message,
                    priority=RulePriority.MEDIUM,
                    score_impact=result.score,
                    execution_time_ms=execution_time,
                    details=result.details or {}
                )
                results.append(rule_result)
                
            except Exception as e:
                logger.error(f"规则 {rule_func.__name__} 执行失败: {str(e)}")
                error_result = RuleResult(
                    rule_name=rule_func.__name__.replace('check_', '').replace('_', ' ').title(),
                    rule_id=rule_func.__name__,
                    matched=False,
                    message=f"规则执行异常: {str(e)}",
                    priority=RulePriority.LOW,
                    score_impact=-5,
                    execution_time_ms=0
                )
                results.append(error_result)
        
        return results
    
    def calculate_total_score(self, results: List[RuleResult]) -> float:
        """计算总分."""
        total_score = 50.0  # 基础分
        
        for result in results:
            total_score += result.score_impact
        
        # 确保分数在0-100范围内
        return max(0.0, min(100.0, total_score))
    
    def check_time_conflict(self, request: AuditRequest) -> SimpleRuleResult:
        """检查时间冲突（基于用户提供的existing_bookings）."""
        try:
            # 从请求中获取现有预订信息
            existing_bookings = getattr(request, 'existing_bookings', None)
            
            if not existing_bookings:
                # 没有提供冲突信息，假设无冲突
                return SimpleRuleResult(
                    passed=True,
                    score=20,
                    message="时间段可用，无冲突",
                    details={"note": "未提供冲突检查数据，假设无冲突"}
                )
            
            # 检查是否有冲突
            conflicts = []
            for booking in existing_bookings:
                if self._times_overlap(
                    request.start_time, request.end_time,
                    booking.get("start_time"), booking.get("end_time")
                ):
                    conflicts.append(booking)
            
            if conflicts:
                return SimpleRuleResult(
                    passed=False,
                    score=-30,
                    message=f"时间段内有 {len(conflicts)} 个预订冲突",
                    details={"conflicts": conflicts}
                )
            else:
                return SimpleRuleResult(
                    passed=True,
                    score=20,
                    message="时间段可用，无冲突"
                )
                
        except Exception as e:
            return SimpleRuleResult(
                passed=False,
                score=-10,
                message=f"时间冲突检查异常: {str(e)}"
            )
    
    def check_applicant_info(self, request: AuditRequest) -> SimpleRuleResult:
        """检查申请人信息完整性（基于用户提供的信息）."""
        try:
            applicant_info = request.applicant_info
            
            # 检查必要字段
            required_fields = ["name", "id", "phone"]
            missing_fields = []
            
            for field in required_fields:
                if not applicant_info.get(field):
                    missing_fields.append(field)
            
            if missing_fields:
                return SimpleRuleResult(
                    passed=False,
                    score=-20,
                    message=f"申请人信息不完整，缺少: {', '.join(missing_fields)}"
                )
            
            # 检查申请人类型（如果提供）
            applicant_type = applicant_info.get("type")
            if applicant_type:
                # 根据用户提供的类型给分
                type_scores = {
                    "admin": 25,
                    "teacher": 20,
                    "student": 15,
                    "external": 5
                }
                score = type_scores.get(applicant_type.lower(), 10)
                return SimpleRuleResult(
                    passed=True,
                    score=score,
                    message=f"申请人类型: {applicant_type}"
                )
            else:
                return SimpleRuleResult(
                    passed=False,
                    score=-15,
                    message="申请人类型未提供，需要进一步确认"
                )
                
        except Exception as e:
            return SimpleRuleResult(
                passed=False,
                score=-10,
                message=f"申请人信息检查异常: {str(e)}"
            )
    
    def check_time_reasonableness(self, request: AuditRequest) -> SimpleRuleResult:
        """检查时间安排合理性."""
        try:
            # 计算使用时长
            duration = (datetime.combine(date.today(), request.end_time) - 
                       datetime.combine(date.today(), request.start_time)).total_seconds() / 3600
            
            if duration <= 0:
                return SimpleRuleResult(
                    passed=False,
                    score=-20,
                    message="时间安排错误：结束时间早于开始时间"
                )
            elif duration > 8:
                return SimpleRuleResult(
                    passed=False,
                    score=-10,
                    message=f"使用时间过长 ({duration:.1f}小时)，超过8小时限制"
                )
            elif duration < 0.5:
                return SimpleRuleResult(
                    passed=False,
                    score=-5,
                    message=f"使用时间过短 ({duration:.1f}小时)，少于0.5小时"
                )
            else:
                return SimpleRuleResult(
                    passed=True,
                    score=15,
                    message="时间安排合理"
                )
                
        except Exception as e:
            return SimpleRuleResult(
                passed=False,
                score=-5,
                message=f"时间检查异常: {str(e)}"
            )
    
    def check_purpose_classification(self, request: AuditRequest) -> SimpleRuleResult:
        """检查使用目的分类."""
        try:
            purpose = request.usage_purpose.lower()
            
            # 根据目的关键词分类
            if any(keyword in purpose for keyword in ["教学", "上课", "课程", "lecture", "class"]):
                return SimpleRuleResult(
                    passed=True,
                    score=20,
                    message="使用目的分类: 学术教学活动"
                )
            elif any(keyword in purpose for keyword in ["会议", "研讨", "workshop", "meeting"]):
                return SimpleRuleResult(
                    passed=True,
                    score=15,
                    message="使用目的分类: 会议研讨活动"
                )
            elif any(keyword in purpose for keyword in ["考试", "测试", "exam", "test"]):
                return SimpleRuleResult(
                    passed=True,
                    score=18,
                    message="使用目的分类: 考试测试活动"
                )
            elif any(keyword in purpose for keyword in ["活动", "讲座", "培训", "training"]):
                return SimpleRuleResult(
                    passed=True,
                    score=12,
                    message="使用目的分类: 培训讲座活动"
                )
            else:
                return SimpleRuleResult(
                    passed=False,
                    score=-5,
                    message="使用目的未能明确分类，需要人工审核"
                )
                
        except Exception as e:
            return SimpleRuleResult(
                passed=False,
                score=-5,
                message=f"目的分类异常: {str(e)}"
            )
    
    def check_capacity_utilization(self, request: AuditRequest) -> SimpleRuleResult:
        """检查容量利用率（基于用户提供的教室容量）."""
        try:
            # 从请求中获取教室容量
            classroom_capacity = getattr(request, 'classroom_capacity', None)
            expected_attendees = request.participants_count
            
            if not classroom_capacity:
                return SimpleRuleResult(
                    passed=True,
                    score=5,
                    message="未提供教室容量信息，无法检查利用率"
                )
            
            utilization = expected_attendees / classroom_capacity * 100
            
            if utilization > 100:
                return SimpleRuleResult(
                    passed=False,
                    score=-25,
                    message=f"参与人数({expected_attendees})超过教室容量({classroom_capacity})"
                )
            elif utilization > 90:
                return SimpleRuleResult(
                    passed=True,
                    score=5,
                    message=f"人数安排较满({utilization:.1f}%利用率)"
                )
            elif utilization < 20:
                return SimpleRuleResult(
                    passed=True,
                    score=10,
                    message=f"人数安排合理({utilization:.1f}%利用率)"
                )
            else:
                return SimpleRuleResult(
                    passed=True,
                    score=15,
                    message=f"人数安排合理({utilization:.1f}%利用率)"
                )
                
        except Exception as e:
            return SimpleRuleResult(
                passed=False,
                score=-5,
                message=f"容量检查异常: {str(e)}"
            )
    
    def check_equipment_availability(self, request: AuditRequest) -> SimpleRuleResult:
        """检查设备可用性（基于用户提供的设备信息）."""
        try:
            required_equipment = request.equipment_needs or []
            available_equipment = getattr(request, 'classroom_equipment', []) or []
            
            if not required_equipment:
                return SimpleRuleResult(
                    passed=True,
                    score=10,
                    message="无特殊设备需求"
                )
            
            missing_equipment = []
            for equipment in required_equipment:
                if equipment not in available_equipment:
                    missing_equipment.append(equipment)
            
            if missing_equipment:
                return SimpleRuleResult(
                    passed=False,
                    score=-20,
                    message=f"教室缺少必需设备: {', '.join(missing_equipment)}"
                )
            else:
                return SimpleRuleResult(
                    passed=True,
                    score=15,
                    message="所需设备齐全"
                )
                
        except Exception as e:
            return SimpleRuleResult(
                passed=False,
                score=-5,
                message=f"设备检查异常: {str(e)}"
            )
    
    def _times_overlap(self, start1, end1, start2, end2) -> bool:
        """检查两个时间段是否重叠."""
        try:
            if isinstance(start2, str):
                start2 = datetime.fromisoformat(start2)
            if isinstance(end2, str):
                end2 = datetime.fromisoformat(end2)
            
            return start1 < end2 and start2 < end1
        except:
            return False